from random import randint

from django.shortcuts import render,redirect,reverse
from django import http
from django.views import View
from django.conf import settings
from QQLoginTool.QQtool import OAuthQQ


from meid_duo.utils.response_code import RETCODE
from django.contrib.auth import login
from django_redis import get_redis_connection
import logging,re,json
from .models import OAuthQQUser,OAUthWeiBoUser
from celery_tasks.sms.tasks import send_sms_code
from users.models import Users
from .utils import generate_openid_signature,check_openid_sign
from carts.utils import merge_cart_cookie_to_redis
from .sinaweibopy3 import APIClient
logger = logging.getLogger("django")

# Create your views here.


class OAuthURLView(View):
    """提供QQ登录界面链接"""
    def get(self,request):
        # 记录从哪个页面来的，等下要回到哪里去
        next = request.GET.get('next', "/")
        # 实例化OAuthQQ对象，获得QQ连接URL
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)
        # 调用方法获得url
        login_url = oauth.get_qq_url()
        return http.JsonResponse({"login_url": login_url,"code": RETCODE.OK,"errmsg": "OK"})


class OAuthUserView(View):
    """QQ登录后回调处理"""
    def get(self,request):
        #获得code值
        code = request.GET.get("code")
        state = request.GET.get("state")
        # 实例化OAuthQQ对象
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
        )
        try:
            #传入获得的code，通过调用oauth对象的get_access_token()方法，获得access_token
            access_token = oauth.get_access_token(code)
            #传入获得的access_token，通过调用oauth对象的get_open_id()方法，获得唯一的openid
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            logger.error(e)

            return http.JsonResponse({'code': RETCODE.OPENIDERR,"errmsg":"QQ服务器不可用，请求失败"})

        # 判断此QQ是否绑定美多商城用户
        try:
            # 用得到的openid去数据库进行比对
            oauth_model = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:  # 数据库查询get未取道值时，会抛出异常（模型类.DoseNotExist）
            # 如果数据库中没有，加载到绑定页面
            openid = generate_openid_signature(openid)   #openid 加密处理
            return render(request, "oauth_callback.html", {"openid":openid})

        # 如果有
        else:
            user = oauth_model.user
            login(request,user)
            response = redirect(state)
            response.set_cookie("username",user.username, max_age=settings.SESSSION_COOKIE_AGE)
            # 登录成功那一刻合并购物车
            merge_cart_cookie_to_redis(request,user,response)
            return response
        # return http.JsonResponse({'openid': openid})


    def post(self,request):
        """用户绑定"""
        # 获取数据
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        openid = request.POST.get('openid')

        if not all([mobile,password,sms_code,openid]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 数据校验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('您输入的手机号格式不正确')

        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')

            # 短信验证码校验后期再补充
        redis_coon = get_redis_connection('verify_code')
        sms_code_server = redis_coon.get('sms_%s' % mobile)  # 获取redis中的短信验证码

        if sms_code_server is None or sms_code != sms_code_server.decode():
            return http.HttpResponseForbidden('短信验证码有误')

        openid = check_openid_sign(openid)  # openid 解密校对
        if openid is None:
            return http.HttpResponseForbidden("openid无效")
        try:
            user = Users.objects.get(mobile=mobile)  # 数据查询
        except Users.DoesNotExist:
            # 如果未查到抛出异常，并新建一条数据
            user = Users.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else: # 如果找到，此用户以绑定手机，进行密码校验
             if user.check_password(password) is False:
                 return http.HttpResponseForbidden('账号或密码错误')
        # 如果代码能执行到这里,用户user绝对已经有了
        # 用户openid和user绑定
        OAuthQQUser.objects.create(
            user=user,
            openid=openid
        )
        # 绑定完成，重定向回原来页面
        login(request,user)
        response = redirect(request.GET.get("state"))
        response.set_cookie("username",user.username,max_age=settings.SESSION_COOKIE_AGE)
        # 登录成功那一刻合并购物车
        merge_cart_cookie_to_redis(request,user,response)
        return response


class WeiBoURLView(View):
    def get(self,request):
        next = request.GET.get('next', "/")
        client = APIClient(
            app_key=settings.APP_KEY,
            app_secret=settings.APP_SECRET,
            redirect_uri=settings.REDIRECT_URL
        )
        login_url = client.get_authorize_url() + '&state='+next

        return http.JsonResponse({"login_url": login_url,"status": RETCODE.OK,"errmsg": "OK"})


class WeiBoReturnView(View):

    def get(self,request):
        return render(request, "sina_callback.html")



class UserBind(View):
    # def get(self,request):
    #     return http.HttpResponse("88")

    def get(self, request):
        code = request.GET.get('code')
        state = request.GET.get('state')
        client = APIClient(
            app_key=settings.APP_KEY,
            app_secret=settings.APP_SECRET,
            redirect_uri=settings.REDIRECT_URL
        )
        try:
            result = client.request_access_token(code)
            access_token = result.access_token
            uid = result.uid
        except Exception as e:
            # logger.error(e)

            return http.HttpResponseBadRequest('服务器不可用')
        try:
            oauth_model = OAUthWeiBoUser.objects.get(uid=access_token)
        except OAUthWeiBoUser.DoesNotExist:
            # openid 加密处理
            access_token = generate_openid_signature(access_token)
            return http.JsonResponse({'access_token': access_token})

        else:
            user = oauth_model.user
            uid = generate_openid_signature(uid)
            context = {
                'user_id': user.id,
                'username': user.username,
                'token': uid
            }
            response = http.JsonResponse(context)
            response.set_cookie("username", user.username, max_age=settings.SESSION_COOKIE_AGE)
            return response

    def post(self,request):
        json_dict = json.loads(request.body.decode())
        password = json_dict.get('password')
        mobile = json_dict.get('mobile')
        sms_code = json_dict.get('sms_code')
        access_token = json_dict.get('access_token')


        if not all([mobile, password, sms_code, access_token]):
            return http.HttpResponseForbidden('缺少必传参数')
            # 数据校验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('您输入的手机号格式不正确')

        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')

            # 短信验证码校验后期再补充

        redis_coon = get_redis_connection('verify_code')
        sms_code_server = redis_coon.get('sms_%s' % mobile)
         # 获取redis中的短信验证码

        if sms_code is None or sms_code != sms_code_server.decode():
            return http.HttpResponseForbidden('短信验证码有误')

        uid = check_openid_sign(access_token)  # openid 解密校对
        if uid is None:
            return http.HttpResponseForbidden("openid无效")
        try:
            user = Users.objects.get(mobile=mobile)  # 数据查询
        except Users.DoesNotExist:
            # 如果未查到抛出异常，并新建一条数据
            user = Users.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else:  # 如果找到，此用户以绑定手机，进行密码校验
            if user.check_password(password) is False:
                return http.HttpResponseForbidden('账号或密码错误')
        # 如果代码能执行到这里,用户user绝对已经有了
        # 用户openid和user绑定
        OAUthWeiBoUser.objects.create(
            user=user,
            uid=uid
        )
        # 绑定完成，重定向回原来页面
        # login(request, user)
        # response = redirect(request.GET.get("state", '/'))
        context = ({
            'user_id': user.id,
            'username': user.username,
            'token': uid
        })

        response = http.JsonResponse(context)
        response.set_cookie("username", user.username, max_age=settings.SESSION_COOKIE_AGE)
        # 登录成功那一刻合并购物车
        merge_cart_cookie_to_redis(request, user, response)
        return response












